#!/bin/sh
# dush - Distributed User Shell
# Execute same command on every node in nodelist
#
# Copyright (c) 2000-2005 by Clunix Inc. All Rights Reserved.
#

NODELIST=
PARALLEL="no"
SKIPSEP="no"
SSH=ssh

trap 'rm -rf /tmp/dush-$$; exit 0' 1 2 15


# Check option
while getopts l:n:psh c; do
    case $c in
	l) NODELIST="$NODELIST `cat $OPTARG`"
	;;
	n) NODELIST="$NODELIST $OPTARG"
	;;
	p) PARALLEL="yes"
	;;
	s) SKIPSEP="yes"
	;;
	h) help=yes
	;;
	*) echo "invalid option"
	exit 1;
	;;
    esac
done

if [ "xxx$help" != xxx ]; then
cat <<EOF
Usage: dush [-n nodelist] [-l nodelist_file] [-ps] command...
       -p : parallel execute
       -s : do not display node separation line
       Default nodelist_file is ./.nodelist, ~/.nodelist or
      /usr/clx/etc/nodelist
EOF
    exit 0
fi

shift `expr $OPTIND - 1`
# Get command to execute
CMD=$*

# Get nodelist to execute
GREP=/bin/grep
if [ "$NODELIST" ];                then NODELIST="$NODELIST"
elif [ -f .nodelist ];             then NODELIST=`$GREP -v '^#' .nodelist`
elif [ -f ~/.nodelist ];           then NODELIST=`$GREP -v '^#' ~/.nodelist`
elif [ -f /usr/clx/etc/nodelist ]; then NODELIST=`$GREP -v '^#' /usr/clx/etc/nodelist`
fi
if [ -z "$NODELIST" ]; then
    echo "Cannot find nodes in .nodelist file at ./, ~/ nor /usr/clx/etc/"
    exit 1
fi


# Check if /bin/usleep exists
if [ -x /bin/usleep ]; then
    SLEEP="/bin/usleep 50000"
else
    SLEEP="sleep 1"
fi


# Do loop for all nodes in NODELIST
if [ "$PARALLEL" = "no" ]; then
    # Do command node by node
    for N in $NODELIST; do
	echo $N | grep '^#' >& /dev/null
	if [ $? -eq 0 ]; then
	    continue
	fi
	if [ xxx$SKIPSEP != xxx"yes" ]; then
	    echo '###' executing in $N
	fi
        ($SSH -n $N "cd $PWD; $CMD" 2>&1) | sed -e "s/^/[$N] /"
    done
else
    # Do command all at once
    mkdir /tmp/dush-$$
    for N in $NODELIST; do
       # Do command in parrallel without node separation line
	echo $N | grep '^#' >& /dev/null
	if [ $? -eq 0 ]; then
	    continue
	fi
       TMP=/tmp/dush-$$/$N.w
       touch $TMP
       ($SSH -n $N "cd $PWD; $CMD" > $TMP 2>&1; \
        sed -e "s/^/[$N] /" $TMP >> $TMP.d; rm -f $TMP) &
    done
    # Need to check if all remove execution end here
    while [ "`ls /tmp/dush-$$/*.w 2> /dev/null`" ]
      do
       $SLEEP
    done
    for F in /tmp/dush-$$/* 
    do
       cat $F
    done
    rm -rf /tmp/dush-$$
fi


exit 0

